package com.gzhryc.shared_device.oem.code.member.services;

import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.IDTools;
import com.gzhryc.common.NumberTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.config.DefaultEnum;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.pay.adaptation.weixin.WXPayNormalPayService;
import com.gzhryc.pay.adaptation.weixin.enums.EWXPayNormalRefundState;
import com.gzhryc.pay.adaptation.weixin.msg.normal.WXPayNormalRefundResponse;
import com.gzhryc.shared_device.base.IPayServiceFactory;
import com.gzhryc.shared_device.base.enums.ELogState;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.enums.ERefundState;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.common.payment.dao.db.AlipayConfig;
import com.gzhryc.shared_device.common.payment.dao.db.PayAccountGroup;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayConfig;
import com.gzhryc.shared_device.common.payment.dao.db.WXRefundOrder;
import com.gzhryc.shared_device.common.payment.dao.enums.EAppType;
import com.gzhryc.shared_device.common.payment.dao.models.CashWithdrawalConfig;
import com.gzhryc.shared_device.common.payment.services.AlipayConfigService;
import com.gzhryc.shared_device.common.payment.services.PayAccountGroupService;
import com.gzhryc.shared_device.common.payment.services.WXPayConfigService;
import com.gzhryc.shared_device.common.payment.services.WXRefundOrderService;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.member.dao.MemberTransferMoneyOrderDao;
import com.gzhryc.shared_device.oem.code.member.dao.db.Member;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberRechargeOrder;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberRechargeRefundOrder;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberTransferMoneyOrder;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberWallet;
import com.gzhryc.shared_device.oem.code.member.dao.enums.MemberEnum;
import com.gzhryc.shared_device.oem.code.member.dao.enums.MemberRechargeOrderEnum;
import com.gzhryc.shared_device.oem.code.member.dao.enums.MemberTransferMoneyOrderEnum;
import com.gzhryc.shared_device.oem.code.member.services.dto.MemberTransferMoneyOrderSearch;
import com.gzhryc.shared_device.oem.code.order.OrderTradeNoPrefix;

public class MemberTransferMoneyOrderService {

    static Logger log = Logger.getLogger(MemberTransferMoneyOrderService.class);

    public static MemberTransferMoneyOrderService self(Date date) {
        return MultiDBTools.getService(MemberTransferMoneyOrderService.class, date);
    }
    
    public static MemberTransferMoneyOrderService self() {
        return MultiDBTools.getService(MemberTransferMoneyOrderService.class, true);
    }


    public static MemberTransferMoneyOrderService self(String jdbcKey,Date date) {
        return MultiDBTools.getService(jdbcKey, MemberTransferMoneyOrderService.class, date);
    }
    
    MemberTransferMoneyOrderDao dao;

    public MemberTransferMoneyOrderService(String jdbcKey,Date date) {
        dao = new MemberTransferMoneyOrderDao(jdbcKey,date);
    }
    
    public MemberTransferMoneyOrderService(String jdbcKey) {
        dao = new MemberTransferMoneyOrderDao(jdbcKey);
    }

    public List<MemberTransferMoneyOrder> findBySearch(MemberTransferMoneyOrderSearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().sameDay("createDate",search.getCreateDay());
        conditions.desc("createDate");
        try {
            return dao.findByCondition(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public Long countBySearch(MemberTransferMoneyOrderSearch search){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().sameDay("createDate",search.getCreateDay());

        try {
            return dao.count(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public MemberTransferMoneyOrder getByTradeNo(String tradeNo){
        try {
            return dao.getById(tradeNo);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public boolean apply(Long memberId, Integer money,OperateInfo operateInfo) throws LogicException {
        if(memberId != null && money != null && money > 0){
            Member member = MemberService.self().getById(memberId);
            if(member == null || StringTools.isBlank(member.getPhone())){
                throw new LogicException("会员或手机号未空");
            }
            MemberWallet wallet = MemberWalletService.self().getByMemberId(memberId);
            if (wallet != null && wallet.getMoney() >= money) {
                Integer receiptMoney = money;
                Date createDate = new Date();
                CashWithdrawalConfig config = null;
                Integer appType = null;
                Integer payType = null;
                
                if(MemberEnum.Type.WxUser.index().equals(member.getType())) {
                	WXPayConfig payConfig = WXPayConfigService.self().getByAppId(member.getAppId());
	                if(payConfig == null || payConfig.getAccountGroupId() == null){
	                	throw new LogicException("未找到提现配置信息");
	                }

	                PayAccountGroup payAccountGroup = PayAccountGroupService.self().getById(payConfig.getAccountGroupId());
	                if(payAccountGroup == null || !payAccountGroup.getMemberCanTransfer() || StringTools.isBlank(payAccountGroup.getMemberTransferConfig())){
	                	throw new LogicException("未开启会员提现功能");
	                }
                    config = JsonTools.fromJson(payAccountGroup.getMemberTransferConfig(),CashWithdrawalConfig.class);
                      
                    appType = EAppType.Weixin.index();
                    payType = EPayType.WXPay.index();
                      
                }else if(MemberEnum.Type.AliUser.index().equals(member.getType())) {
                	AlipayConfig payConfig = AlipayConfigService.self().getByAppId(member.getAppId());
	                if(payConfig == null || payConfig.getAccountGroupId() == null){
	                	throw new LogicException("未找到提现配置信息");
	                }

	                PayAccountGroup payAccountGroup = PayAccountGroupService.self().getById(payConfig.getAccountGroupId());
	                if(payAccountGroup == null || !payAccountGroup.getMemberCanTransfer() || StringTools.isBlank(payAccountGroup.getMemberTransferConfig())){
	                	throw new LogicException("未开启会员提现功能");
	                }
                    config = JsonTools.fromJson(payAccountGroup.getMemberTransferConfig(),CashWithdrawalConfig.class);
                      
                    appType = EAppType.Aliyun.index();
                    payType = EPayType.Alipay.index();
                }

                if(config != null && checkTransferConfig(config)) {
                	//计算服务费
                	if(config.getServiceCharge() > 0){
                        receiptMoney = money - NumberTools.proportion(money,config.getServiceCharge());
                    }
                	
                	String tradeNo = OrderTradeNoPrefix.MEMBER_TRANSFER_MONEY_ORDER + IDTools.getTimestampSecondID() + RandomUtils.nextInt(100,999);
                	
	            	MemberTransferMoneyOrder transferMoneyOrder = new MemberTransferMoneyOrder();
	                transferMoneyOrder.setTradeNo(tradeNo);
	                transferMoneyOrder.setMemberId(memberId);
	                if(StringTools.isNotBlank(member.getName())){
	                     transferMoneyOrder.setMemberName(member.getName() + "(昵称：" + member.getNickname() + ")");
	                }else {
	                     transferMoneyOrder.setMemberName(member.getNickname());
	                }
	                transferMoneyOrder.setMemberPhone(member.getPhone());
	                transferMoneyOrder.setAppId(member.getAppId());
	                transferMoneyOrder.setAppType(appType);
	                transferMoneyOrder.setPayType(payType);
	                transferMoneyOrder.setMoney(money);
	                
	                transferMoneyOrder.setProfitProportion(config.getServiceCharge());
	                transferMoneyOrder.setReceiptMoney(receiptMoney);
	                transferMoneyOrder.setCreateDate(createDate);
                	
	                boolean flag = false;
	                JdbcSession.begin();
	                try {
	                    Long freezeMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(money));
	                    if (MemberWalletService.self().freezeMoney(memberId,freezeMoney,operateInfo)) {
                            if (dao.insert(transferMoneyOrder) > 0) {
                                JdbcSession.commit();
                                flag = true;
                            }
	                    }
	                } catch (SQLException e) {
	                    log.error(e.getMessage(), e);
	                } finally {
	                    JdbcSession.end();
	                }
	                
	                if(flag){
	                    String logContent = "会员提现申请入库";
	                    Integer logState = ELogState.Success.index();
	                    MemberTransferMoneyOrderLogService.self().addLogItem(transferMoneyOrder.getTradeNo(),transferMoneyOrder.getCreateDate()
	                            ,operateInfo,logContent,logState,null);
	                    return true;
	                }
                }
            } else {
                throw new LogicException("会员余额不足");
            }
        }
        return false;
    }
    
    /**
     * 检查提现配置
     * @param config
     * @return
     * @throws LogicException
     */
    private boolean checkTransferConfig(CashWithdrawalConfig config) throws LogicException {
        // 检查提现时间
        boolean flag = false;
        String weekNames = "";
        if (config.getMonthStartDay() != null && config.getMonthEndDay() != null) {
            int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
            if (day < config.getMonthStartDay() || day > config.getMonthEndDay()) {
                throw new LogicException("请在每月" + config.getMonthStartDay() + "号-" + config.getMonthEndDay() + "号提现");
            }
        }
        if (StringUtils.isNotBlank(config.getCashWithdrawalWeeks())) {
            int week = DateTools.getWeek(new Date());
            String[] names = config.getCashWithdrawalWeeks().split(",");
            for (String name : names) {
                if (week == DefaultEnum.Weeks.valueOf(name).index()) {
                    if (StringUtils.isNotBlank(config.getCashWithdrawalTimes())) {
                        String[] times = config.getCashWithdrawalTimes().split(" - ");
                        if (times.length == 2) {
                            Date currentDate = new Date();
                            try {
                                String dateStr = DateFormatUtils.format(currentDate, "yyyy-MM-dd");
                                String startStr = dateStr + " " + times[0];
                                Date startDate = DateUtils.parseDate(startStr, "yyyy-MM-dd HH:mm:ss");
                                String endStr = dateStr + " " + times[1];
                                Date endDate = DateUtils.parseDate(endStr, "yyyy-MM-dd HH:mm:ss");

                                if (startDate.before(currentDate) && endDate.after(currentDate)) {
                                    flag = true;
                                }
                            } catch (ParseException e) {
                                log.error(e.getMessage(), e);
                            }
                        }
                    }
                }
                weekNames = weekNames + "," + DefaultEnum.Weeks.valueOf(name).note();
            }
            weekNames = weekNames.substring(1);
        }

        if (!flag) {
            throw new LogicException("请在" + weekNames + "的" + config.getCashWithdrawalTimes() + "提现");
        }
    	return flag;
    }

    public void rechargeOrderRefundCheckFinish(String tradeNo,OperateInfo operateInfo) {
        if (StringTools.isNotBlank(tradeNo)) {
            MemberTransferMoneyOrder transferMoneyOrder = getByTradeNo(tradeNo);
            if (transferMoneyOrder == null || !MemberTransferMoneyOrderEnum.State.Processing.index().equals(transferMoneyOrder.getState())) {
                return;
            }
            List<MemberRechargeRefundOrder> refundOrderList = MemberRechargeRefundOrderService.self().findByTransferTradeNo(transferMoneyOrder.getTradeNo());
            if (refundOrderList != null && refundOrderList.size() > 0) {
                boolean flag = true;
                Integer refundMoney = 0;

                for (MemberRechargeRefundOrder refundOrder : refundOrderList) {
                    if (ERefundState.Success.index().equals(refundOrder.getRefundState())) {
                        refundMoney = refundMoney + refundOrder.getRefundMoney();
                    }else if(ERefundState.Wait.index().equals(refundOrder.getRefundState())){
                        flag = false;
                        break;
                    }
                }

                if (flag && refundMoney >= transferMoneyOrder.getReceiptMoney()) {
                    //处理完成
                    Conditions conditions = new Conditions(MemberTransferMoneyOrder.class);
                    conditions.and().is("tradeNo", transferMoneyOrder.getTradeNo());
                    conditions.and().is("state", MemberTransferMoneyOrderEnum.State.Processing.index());

                    MemberTransferMoneyOrder updateEntity = new MemberTransferMoneyOrder();
                    updateEntity.setState(MemberTransferMoneyOrderEnum.State.Success.index());

                    String logContent = "会员提现处理完成";
                    Integer logState = ELogState.Fail.index();
                    String errorMsg = "修改状态失败";
                    
                    try {
                        if (dao.updateNotNull(updateEntity, conditions) > 0) {
                        	logState = ELogState.Success.index();
                        	errorMsg = null;
                        }else {
                            log.error("{{0}}会员提现申请{{1}}处理成功，但修改状态失败", transferMoneyOrder.getMemberId(), transferMoneyOrder.getTradeNo());
                        }
                    } catch (SQLException e) {
                        log.error(e.getMessage(), e);
                        errorMsg = "SQL错误，信息：" + e.getMessage();
                    }
                    
                    MemberTransferMoneyOrderLogService.self().addLogItem(transferMoneyOrder.getTradeNo(),transferMoneyOrder.getCreateDate()
                            ,operateInfo,logContent,logState,errorMsg);
                }
            }
        }
    }

    /**
     * 系统处理转账
     * @return
     */
    public boolean autoProcessing(MemberTransferMoneyOrder order,IPayServiceFactory payServiceFactory,OperateInfo operateInfo) throws LogicException {
        if (!MemberTransferMoneyOrderEnum.State.Check.index().equals(order.getState())) {
            throw new LogicException("会员提现订单已处理");
        }

        WXPayConfig payConfig = WXPayConfigService.self().getByAppId(order.getAppId());
        if(payConfig == null || payConfig.getAccountGroupId() == null){
            throw new LogicException("未找到提现配置信息");
        }

        PayAccountGroup payAccountGroup = PayAccountGroupService.self().getById(payConfig.getAccountGroupId());
        if(payAccountGroup == null || !payAccountGroup.getMemberCanTransfer() || StringTools.isBlank(payAccountGroup.getMemberTransferConfig())){
            throw new LogicException("未开启会员提现功能");
        }

        CashWithdrawalConfig config = JsonTools.fromJson(payAccountGroup.getMemberTransferConfig(),CashWithdrawalConfig.class);
        if (config.getAutoMaxMoney() <= 0) {
            throw new LogicException("自动转账已关闭");
        }
        if (config.getAutoMaxMoney() < order.getMoney()) {
            throw new LogicException("提现超过自动转账金额");
        }

        //检查是否可以自动处理
        List<MemberRechargeOrder> orderList = findRechargeOrder(order);
        if (orderList == null || orderList.size() <= 0) {
            throw new LogicException("暂无可退款的支付订单");
        }

        //自动转账
        Conditions conditions = new Conditions(MemberTransferMoneyOrder.class);
        conditions.and().is("tradeNo", order.getTradeNo());
        conditions.and().is("state", MemberTransferMoneyOrderEnum.State.Check.index());

        MemberTransferMoneyOrder updateEntity = new MemberTransferMoneyOrder();
        updateEntity.setState(MemberTransferMoneyOrderEnum.State.Processing.index());
        updateEntity.setHandleType(MemberTransferMoneyOrderEnum.HandleType.RefundProcessing.index());
        String operator = "["+operateInfo.getOperatorTypeName()+"]" + operateInfo.getOperator();
        updateEntity.setOperator(operator);
        updateEntity.setHandleDate(new Date());

        try {
            if (dao.updateNotNull(updateEntity, conditions) > 0) {
                order.setState(updateEntity.getState());
                order.setHandleType(updateEntity.getHandleType());
                order.setOperator(updateEntity.getOperator());
                order.setHandleDate(updateEntity.getHandleDate());
                rechargeOrderRefundHandle(order, orderList,payServiceFactory,operateInfo);
                return true;
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

    /**
     * 驳回提现
     * @param tradeNo
     * @param operateInfo
     * @return
     * @throws LogicException
     */
    public boolean reject(String tradeNo, String rejectNote,OperateInfo operateInfo) throws LogicException {
        if(StringTools.isNotBlank(tradeNo)){
            MemberTransferMoneyOrder order = getByTradeNo(tradeNo);
            if(order == null){
                throw new LogicException("未找到会员提现订单");
            }
            String logContent = "驳回提现";

            if(!MemberTransferMoneyOrderEnum.State.Check.index().equals(order.getState())){
                if(MemberTransferMoneyOrderEnum.State.Processing.index().equals(order.getState())){
                    //检查时间
                    Long hour = DateTools.differenceHour(order.getHandleDate(),new Date());
                    if(hour < 3){
                        MemberTransferMoneyOrderLogService.self().addLogItem(order.getTradeNo(),order.getCreateDate()
                                ,operateInfo,logContent, ELogState.Fail.index(),"会员提现订单转账中");
                        throw new LogicException("会员提现订单转账中，请3个小时后再处理");
                    }
                }else {
                    throw new LogicException("会员提现订单已处理");
                }
            }

            Integer logState = ELogState.Success.index();
            String errorMsg = null;

            Conditions conditions = new Conditions(MemberTransferMoneyOrder.class);
            conditions.and().is("tradeNo", order.getTradeNo());
            conditions.and().is("state", order.getState());

            MemberTransferMoneyOrder updateEntity = new MemberTransferMoneyOrder();
            updateEntity.setState(MemberTransferMoneyOrderEnum.State.Reject.index());
            if(order.getHandleType() == null) {
            	updateEntity.setHandleType(MemberTransferMoneyOrderEnum.HandleType.returnWallet.index());
            }
            String operator = "[" + operateInfo.getOperatorTypeName() + "]" + operateInfo.getOperator();
            updateEntity.setOperator(operator);
            updateEntity.setRejectNote(rejectNote);
            updateEntity.setHandleDate(new Date());

            JdbcSession.begin();
            try {
                if (dao.updateNotNull(updateEntity, conditions) > 0) {
                    Long money = NumberTools.changeMoneyLi(NumberTools.changeMoney(order.getMoney()));
                    if (MemberWalletService.self().unfreezeMoney(order.getMemberId(), money, operateInfo)) {
                        JdbcSession.commit();
                    } else {
                        logState = ELogState.Fail.index();
                        errorMsg = "解冻金额失败";
                        log.error("驳回{{0}}会员提现时解冻金额失败", order.getTradeNo());
                    }
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
                logState = ELogState.Fail.index();
                errorMsg = e.getMessage();
            } finally {
                JdbcSession.end();
            }

            MemberTransferMoneyOrderLogService.self().addLogItem(order.getTradeNo(),order.getCreateDate(),operateInfo,logContent,logState,errorMsg);
            return ELogState.Success.index().equals(logState);
        }
        return false;
    }

    /**
     * 人工处理
     * @param tradeNo
     * @param operateInfo
     * @return
     */
    public boolean manualProcessing(String tradeNo,Integer handleType,IPayServiceFactory payServiceFactory,OperateInfo operateInfo)throws LogicException{
        if(StringTools.isNotBlank(tradeNo)) {
            MemberTransferMoneyOrder order = getByTradeNo(tradeNo);
            if (order == null) {
                throw new LogicException("未找到会员提现订单");
            }

            if (!MemberTransferMoneyOrderEnum.State.Check.index().equals(order.getState())) {
                throw new LogicException("会员提现订单已处理");
            }

            if(MemberTransferMoneyOrderEnum.HandleType.OfflineProcessing.index().equals(handleType)){
                return officeProcessing(order,operateInfo);
            }else if(MemberTransferMoneyOrderEnum.HandleType.RefundProcessing.index().equals(handleType)){
                //检查是否可以自动处理
                List<MemberRechargeOrder> orderList = findRechargeOrder(order);
                if (orderList == null || orderList.size() <= 0) {
                    throw new LogicException("暂无可退款的支付订单");
                }

                //自动转账
                Conditions conditions = new Conditions(MemberTransferMoneyOrder.class);
                conditions.and().is("tradeNo", order.getTradeNo());
                conditions.and().is("state", MemberTransferMoneyOrderEnum.State.Check.index());

                MemberTransferMoneyOrder updateEntity = new MemberTransferMoneyOrder();
                updateEntity.setState(MemberTransferMoneyOrderEnum.State.Processing.index());
                updateEntity.setHandleType(MemberTransferMoneyOrderEnum.HandleType.RefundProcessing.index());
                String operator = "["+operateInfo.getOperatorTypeName()+"]" + operateInfo.getOperator();
                updateEntity.setOperator(operator);
                updateEntity.setHandleDate(new Date());

                Integer logState = ELogState.Success.index();
                String errorMsg = null;
                
                try {
                    if (dao.updateNotNull(updateEntity, conditions) > 0) {
                        order.setState(updateEntity.getState());
                        order.setHandleType(updateEntity.getHandleType());
                        order.setOperator(updateEntity.getOperator());
                        order.setHandleDate(updateEntity.getHandleDate());
                    }else {
                    	logState = ELogState.Fail.index();
                    	errorMsg = "修改数据库失败";
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                    logState = ELogState.Fail.index();
                	errorMsg = "SQL错误，信息：" + e.getMessage();
                }
                
                MemberTransferMoneyOrderLogService.self().addLogItem(order.getTradeNo(),order.getCreateDate()
           			 ,operateInfo,"人工处理-充值退款方式提现",logState,errorMsg);
                
                if(ELogState.Success.index().equals(logState)) {
                	 //触发退款
                    rechargeOrderRefundHandle(order, orderList,payServiceFactory,operateInfo);
                    return true;
                }
            }
        }
        return false;
    }

    private boolean officeProcessing(MemberTransferMoneyOrder order,OperateInfo operateInfo)throws LogicException{
        if(order != null) {
            if (!MemberTransferMoneyOrderEnum.State.Check.index().equals(order.getState())) {
                throw new LogicException("会员提现订单已处理");
            }

            String logContent = "确认下线处理提现";
            Integer logState = ELogState.Success.index();
            String errorMsg = null;

            Conditions conditions = new Conditions(MemberTransferMoneyOrder.class);
            conditions.and().is("tradeNo", order.getTradeNo());
            conditions.and().is("state", MemberTransferMoneyOrderEnum.State.Check.index());

            MemberTransferMoneyOrder updateEntity = new MemberTransferMoneyOrder();
            updateEntity.setState(MemberTransferMoneyOrderEnum.State.Success.index());
            updateEntity.setHandleType(MemberTransferMoneyOrderEnum.HandleType.OfflineProcessing.index());
            String operator = "["+operateInfo.getOperatorTypeName()+"]" + operateInfo.getOperator();
            updateEntity.setOperator(operator);
            updateEntity.setHandleDate(new Date());

            JdbcSession.begin();
            try {
                if (dao.updateNotNull(updateEntity, conditions) > 0) {
                    Long money = NumberTools.changeMoneyLi(NumberTools.changeMoney(order.getMoney()));
                    if (MemberWalletService.self().reduceFreezeMoney(order.getMemberId(), money, operateInfo)) {
                        JdbcSession.commit();
                    } else {
                        logState = ELogState.Fail.index();
                        errorMsg = "解冻金额失败";
                        log.error("驳回{{0}}会员提现时解冻金额失败", order.getTradeNo());
                    }
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            } finally {
                JdbcSession.end();
            }

            MemberTransferMoneyOrderLogService.self().addLogItem(order.getTradeNo(),order.getCreateDate(),operateInfo,logContent,logState,errorMsg);
            return ELogState.Success.index().equals(logState);
        }
        return false;
    }

    /**
     * 获取可退款的充值订单
     * @return
     */
    private List<MemberRechargeOrder> findRechargeOrder(MemberTransferMoneyOrder transferMoneyOrder) {
        //获取最旧充值订单
        List<MemberRechargeOrder> rechargeOrderList = MemberRechargeOrderService.self(transferMoneyOrder.getCreateDate())
        		.findOldCanRefund(transferMoneyOrder.getMemberId(),transferMoneyOrder.getPayType());
        if (rechargeOrderList == null || rechargeOrderList.size() <= 0) {
            //检查上一年
            Date year = DateUtils.addYears(transferMoneyOrder.getCreateDate(), -1);
            rechargeOrderList = MemberRechargeOrderService.self(year).findOldCanRefund(transferMoneyOrder.getMemberId()
            		,transferMoneyOrder.getPayType());
        }

        if (rechargeOrderList != null && rechargeOrderList.size() > 0) {
            List<MemberRechargeOrder> useOrder = new ArrayList<>();
            //300天计算过期
            Date today = new Date();
            Integer money = 0;
            for (MemberRechargeOrder rechargeOrder : rechargeOrderList) {
                Integer days = DateTools.differenceDay(rechargeOrder.getCreateDate(), today);
                if (days > 300) {
                    MemberRechargeOrderService.self(rechargeOrder.getCreateDate()).updateState(rechargeOrder.getTradeNo(), MemberRechargeOrderEnum.State.SuccessEnd.index());
                } else {
                    Integer residueMoney = rechargeOrder.getResidueMoney();
                    if (residueMoney <= 1) {
                        //小于1分钱，则代表退款完毕
                        MemberRechargeOrderService.self(rechargeOrder.getCreateDate()).updateState(rechargeOrder.getTradeNo(), MemberRechargeOrderEnum.State.RefundFinish.index());
                    } else {
                        useOrder.add(rechargeOrder);
                        money = money + residueMoney;
                        if (money >= transferMoneyOrder.getReceiptMoney()) {
                            break;
                        }
                    }
                }
            }
            if (useOrder.size() > 0) {
                return useOrder;
            }
        }
        return null;
    }

    /**
     * 以充值订单退款的方式提现
     * @param order
     * @param useOrder
     * @param payServiceFactory
     * @param operateInfo
     * @throws LogicException
     */
    private void rechargeOrderRefundHandle(MemberTransferMoneyOrder order, List<MemberRechargeOrder> useOrder,
                                           IPayServiceFactory payServiceFactory, OperateInfo operateInfo) throws LogicException {
        if (useOrder.size() > 0) {
            List<MemberRechargeRefundOrder> refundOrderList = new ArrayList<>();
            
            Integer logState = ELogState.Success.index();
            String errorMsg = null;

            JdbcSession.begin();
            try {
                int money = order.getReceiptMoney();
                String operateNote = "会员钱包金额提现";
                
                for (MemberRechargeOrder rechargeOrder : useOrder) {
                    Integer residueMoney = rechargeOrder.getResidueMoney();
                    Integer refundMoney = 0;
                    if (money >= residueMoney) {
                        refundMoney = residueMoney;
                    } else {
                        refundMoney = money;
                    }

                    MemberRechargeRefundOrder refundOrder = MemberRechargeRefundOrderService.self()
                            .createRefundOrder(rechargeOrder, order.getTradeNo(), refundMoney, operateNote);
                    if (refundOrder != null) {
                        money = money - refundOrder.getRefundMoney();
                        refundOrderList.add(refundOrder);
                    }

                    if (money <= 0) {
                        JdbcSession.commit();
                        break;
                    }
                }
                
                if (money > 0) {
                	logState = ELogState.Fail.index();
                 	errorMsg = "没有足够的充值订单进行退款";
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
                logState = ELogState.Fail.index();
            	errorMsg = "SQL错误，信息：" + e.getMessage();
            } finally {
                JdbcSession.end();
            }
            
            MemberTransferMoneyOrderLogService.self().addLogItem(order.getTradeNo(),order.getCreateDate()
          			 ,operateInfo,"创建充值退款订单",logState,errorMsg);
               
            if(ELogState.Success.index().equals(logState) && refundOrderList.size() > 0) {
                //触发第三方退款
                for (MemberRechargeRefundOrder refundOrder : refundOrderList) {
                    if (EPayType.WXPay.index().equals(refundOrder.getPayType())) {
                        WXRefundOrder wxRefundOrder = WXRefundOrderService.self(refundOrder.getCreateDate()).getByTradeNo(refundOrder.getTradeNo());
                        WXPayNormalPayService payService = payServiceFactory.getWXPayNormalPayService(wxRefundOrder.getAppId(), EBusinessType.RECHARGE.index());
                        if (payService != null) {
                            WXPayNormalRefundResponse externalRefundOrder = payService.applyRefundOrder(wxRefundOrder);
                            if (externalRefundOrder != null) {
                                if (EWXPayNormalRefundState.SUCCESS.name().equals(externalRefundOrder.getStatus())) {
                                    //直接退款成功，修改退款订单状态
                                    WXRefundOrderService.self(wxRefundOrder.getCreateDate()).toSuccess(wxRefundOrder.getTradeNo(),externalRefundOrder.getRefund_id()
                                            ,JsonTools.toJson(externalRefundOrder));
                                    wxRefundOrder.setRefundStatus(ERefundState.Success.index());
                                    MemberRechargeRefundOrderService.self().refundResult(wxRefundOrder,operateInfo);
                                } else if (EWXPayNormalRefundState.CLOSED.name().equals(externalRefundOrder.getStatus())
                                        || EWXPayNormalRefundState.ABNORMAL.name().equals(externalRefundOrder.getStatus())) {
                                    log.error("{{0}}退款订单处理失败，第三方返回", refundOrder.getTradeNo(), externalRefundOrder);
                                    errorMsg = "退款订单异常或已关闭";
                                    if (StringTools.isNotBlank(externalRefundOrder.getMessage())) {
                                        errorMsg = externalRefundOrder.getMessage();
                                    }
                                    WXRefundOrderService.self(wxRefundOrder.getCreateDate()).toFail(wxRefundOrder.getTradeNo(),errorMsg,JsonTools.toJson(externalRefundOrder));
                                    wxRefundOrder.setRefundStatus(ERefundState.Fail.index());
                                    MemberRechargeRefundOrderService.self().refundResult(wxRefundOrder,operateInfo);
                                    logState = ELogState.Fail.index();
                                } else if (StringTools.isNotBlank(externalRefundOrder.getCode()) && StringTools.isNotBlank(externalRefundOrder.getMessage())) {
                                    WXRefundOrderService.self(wxRefundOrder.getCreateDate()).toFail(wxRefundOrder.getTradeNo(),externalRefundOrder.getMessage(),JsonTools.toJson(externalRefundOrder));
                                    wxRefundOrder.setRefundStatus(ERefundState.Fail.index());
                                    MemberRechargeRefundOrderService.self().refundResult(wxRefundOrder,operateInfo);
                                    if("INVALID_REQUEST".equals(externalRefundOrder.getCode())){
                                        //订单没有足够金额退款
                                        MemberRechargeOrderService.self(refundOrder.getCreateDate()).updateState(refundOrder.getRechargeTradeNo(),MemberRechargeOrderEnum.State.RefundFinish.index());
                                    }
                                    errorMsg = externalRefundOrder.getMessage();
                                    logState = ELogState.Fail.index();
                                }
                            } else {
                                errorMsg = "微信退款接口无响应";
                                WXRefundOrderService.self(wxRefundOrder.getCreateDate()).toFail(wxRefundOrder.getTradeNo(),errorMsg,JsonTools.toJson(externalRefundOrder));
                                wxRefundOrder.setRefundStatus(ERefundState.Fail.index());
                                MemberRechargeRefundOrderService.self().refundResult(wxRefundOrder,operateInfo);
                                logState = ELogState.Fail.index();
                            }
                        } else {
                            log.error("会员提现处理，未找到对应的微信支付服务，APPID：{{0}}", wxRefundOrder.getAppId());
                            errorMsg = "未找到对应的微信支付服务";
                            logState = ELogState.Fail.index();
                        }
                    }
                }
                
                MemberTransferMoneyOrderLogService.self().addLogItem(order.getTradeNo(),order.getCreateDate()
             			 ,operateInfo,"申请第三方支付退款",logState,errorMsg);
            }
        }
    }

    public boolean deleteByTradeNo(String tradeNo) throws LogicException {
    	MemberTransferMoneyOrder transferMoneyOrder = getByTradeNo(tradeNo);
    	if(transferMoneyOrder == null || MemberTransferMoneyOrderEnum.State.Check.index().equals(transferMoneyOrder.getState())
    			|| MemberTransferMoneyOrderEnum.State.Processing.index().equals(transferMoneyOrder.getState())) {
    		throw new LogicException("提现未处理，请先处理");
    	}
    	
    	JdbcSession.begin();
        try {
        	Conditions condition = new Conditions(transferMoneyOrder.getClass());
        	condition.and().is("tradeNo", transferMoneyOrder.getTradeNo());
        	condition.and().is("state", transferMoneyOrder.getState());
        	
        	if(dao.deleteByCondition(condition) > 0) {
        		//删除日志
        		if(MemberTransferMoneyOrderLogService.self().deleteByTradeNo(tradeNo)) {
        			//删除转账记录
        			if(EPayType.WXPay.index().equals(transferMoneyOrder.getPayType())) {
        				
        			}
        			JdbcSession.commit();
        			return true;
        		}
        	}
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        } finally {
            JdbcSession.end();
        }
    	return false;
    }
}
